﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SHDocVw;
using mshtml;
using System.Text.RegularExpressions;
using System.Threading;

namespace Password_Changer
{
    class Hacker
    {
        private InternetExplorer browser = new InternetExplorer();
        private HTMLDocument document { get { return (HTMLDocument)browser.Document; } }

        private RequestPage login = new RequestPage()
        {
            PageRegex = @"https?://www.facebook.com/(login.php?.*)?",
            Data = new List<InputElement>() {  
                new InputElement()
                { ID = "email", Value = "thordickinson@yahoo.com"},
                new InputElement()
                {ID ="pass", Value ="751568"}
            },
            LabelWrapperSubmitControlId = "loginbutton"
        };

        private RequestPage confirmation = new RequestPage()
        {
            PageRegex = @"https?://www.facebook.com/checkpoint/",
            Data = new List<InputElement>() { 
                new InputElement()
                {ID ="approvals_code", Value = "643305"}
            },
            LabelWrapperSubmitControlId = "checkpointSubmitButton"
        };

        private RequestPage doNotSaveDevice = new RequestPage()
        {
            PageRegex = @"https?://www.facebook.com/checkpoint/",
            Data = new List<InputElement>() {  
                new InputElement()
                {ID ="machine_name", Value = "Home Device"}
            },
            LabelWrapperSubmitControlId = "checkpointSecondaryButton"
        };

        private RequestPage saveDevice = new RequestPage()
        {
            PageRegex = @"https?://www.facebook.com/checkpoint/",
            Data = new List<InputElement>() { 
                new InputElement()
                {ID ="machine_name",Value =  "Home Device"}
            },
            LabelWrapperSubmitControlId = "checkpointSubmitButton"
        };

        private RequestPage changePassword = new RequestPage()
        {
            URL = @"https://www.facebook.com/settings?ref=mb#!/settings?tab=account&section=password&view",
            Data = new List<InputElement>()  { 
                new InputElement(){ID ="password_old", Value ="751568"},
                new InputElement(){ID ="password_new", Value ="134679"},
                new InputElement(){ID ="password_confirm", Value ="134679"}
            }
        };


        public Hacker()
        {
            browser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(browser_DocumentComplete);
            navigate(@"http://www.facebook.com/");
            browser.Visible = true;
            Thread.Sleep(500000);

        }

        public void navigate(string url)
        {
            browser.Navigate3(url);
        }

        void browser_DocumentComplete(object pDisp, ref object URL)
        {
            IHTMLElement input = (IHTMLElement)document.FindInputElement(new InputElement() { ID = "email" });           
            HTMLFormElement form = input.getNearestParent<HTMLFormElement>();
            setFormInputElementsValue(form, new Dictionary<string, string>() { {"email", "thordickinson@yahoo.com"},{"pass","751568"}});
            form.submit();
            
            //form.submit();
            //sendEmailPassword();
        }

        private void setFormInputElementsValue(HTMLFormElement form, Dictionary<string,string> data) {
            IHTMLElementCollection inputs = form.getElementsByTagName("input");
            for (int i = 0; i < inputs.length; i++) {
                HTMLInputElement input = ((HTMLInputElement)inputs.item(i));
                string name = input.name;
                if (!string.IsNullOrEmpty(name) && data.ContainsKey(name)) {
                    input.innerText = data[name];
                }
            }
            
        }

        private void sendEmailPassword()
        {
            if (!isLogged())
            {
                if (!commitForm(login))
                    if (!commitForm(confirmation))
                        commitForm(doNotSaveDevice);
            }
            else
            {
                commitForm(changePassword);
            }
        }

      

        public Boolean commitForm(RequestPage page)
        {
            if (page.URL != null)
            {
                navigate(page.URL);
            }
            if (!isInPage(page))
            {
                return false;
            }
            foreach (InputElement element in page.Data)
            {
                if (!string.IsNullOrEmpty(element.ID))
                {
                    HTMLInputTextElement input = document.getElementById<HTMLInputTextElement>(element.ID);
                    input.select();
                    //input.setAttribute("value", element.Value, 2);
                    input.innerText = element.Value;
                    //writeType((input));
                }
                //TODO Agregar el caso en que la página esté escrita en otros idiomas.
                else if (!string.IsNullOrEmpty(element.Label))
                {
                    document.GetElementByLabel(element.Label).Single().innerText = element.Value;
                }
            }

            if (page.SubmitControlId != null)
                document.getElementById<HTMLInputTextElement>(page.SubmitControlId).click();

            else if (page.LabelWrapperSubmitControlId != null)
                document.getElementById<HTMLInputTextElement>(document.getElementById<HTMLLabelElement>(page.LabelWrapperSubmitControlId).htmlFor).click();
            return true;
        }

        private Boolean isInPage(RequestPage page)
        {
            if (!document.URLMatches(page.PageRegex))
                return false;
            IEnumerable<string> ids = from data in page.Data
                                      where !string.IsNullOrEmpty(data.ID)
                                      select data.ID;
            return document.ContainsAllElementIDs(ids);
        }




        private void writeType(object val)
        {
            Console.WriteLine(val.GetType());
        }

        private Boolean isLogged()
        {
            object val = document.getElementById<object>("jewelContainer");
            return val != null;
        }

        static void Main(string[] args)
        {
            new Hacker();
        }
    }


}
